#!/usr/bin/env python
# -*- coding: UTF-8 -*-

#------------------------------------------------------------------------------
# Copyright (c) 2010 Giuseppe Buzzanca (PiDy) <giuseppebuzzanca@gmail.com>.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Contributors:
#     Giuseppe Buzzanca (PiDy) <giuseppebuzzanca@gmail.com>
#         initial API and implementation
#------------------------------------------------------------------------------

import HTMLParser
import urllib
from google.appengine.api import urlfetch
import logging

class Activity:

    """This class represent a Google Buzz Activity.
    Return an activity object, content and originalLink are required.
    """


    def __init__(self, content = None, originalLink = None):
        self.content = content
        """This is the content of a buzz.
        It's the pure text/html present into the activity.
        """
        self.originalLink = originalLink
        """This is the original link of the buzz.
        """
        self._geoPoints = ()
        """This is a tuple that represent the geographical position of the buzz,
        """
        self._attachments = []
        """A list of dictionaries, the dictionary have three keys:
        type: the typology of attachment 
        title: it's a description of the link
        link: it's the link itself
        """
        self._source = ''
        """This is the cross-post source of the activity.
        It's specify if this entry is a secondary duplicate of a primary version of post.
        Can be assumes this values:
        from twitter: tag:twitter.com
        """

    def removeNewLine(self):
        """Remove all the new line characters from the self.content.
        Change the self.content in an only row. 
        """
        self.content = self.content.replace("\n", "")

    def unescapeContent(self):
        """Returns the given HTML with ampersands, quotes and carets decoded.
        In other word it replaces the reserved characters of the HTML with their values.
        """
        self.content = self.content.replace('&amp;', '&').replace('&lt;', '<').replace('&gt;', '>').replace('&quot;', '"').replace('&#39;', "'")

    def setAttach(self, type, title, link):
        """Add a dictionary to the attachments list"""
        d = {'type':type, 'title':title, 'link':link}
        self._attachments.append(d)

    def getAttachs(self):
        """Return the list of registered attachments."""
        return self._attachments

    def setGeoPoints(self, lat, long):
        """Set the geoPoints attribute with a tuple of lat and long."""
        self._geoPoints = lat, long

    def getGeoPoints(self):
        """Return the registered geoPoints."""
        return self._geoPoints

    def setSource(self, source):
        """Set the source string of the crossposted activity."""
        self._source = source

    def getSource(self):
        """Return the source string. If empty return None."""
        return self._source

    def parseContent(self):
        """Parse content and remove the html formatting,
        maintain only the pure text.
        """
        self.content = ParseContent(self.content).content

    def getShortUrl(self, longurl, bitlyLogin = None, bitlyApiKey = None):
        """Return a short url version.
        If bitlyLoging and bitlyApiKey are passed it uses the api.j.mp service
        otherwise it uses the is.gd service.
        Return None in case of error.
        """
        if bitlyLogin and bitlyLogin:
            pf = {'login': bitlyLogin, "apiKey": bitlyApiKey, "longUrl": longurl, "format": "txt"}
            pd = urllib.urlencode(pf)
            result = urlfetch.fetch(url = "http://api.j.mp/v3/shorten?" + pd)
        else:
            pf = {'longurl': longurl}
            pd = urllib.urlencode(pf)
            result = urlfetch.fetch(url = "http://is.gd/api.php?" + pd)
        if result.status_code == 200:
            return result.content.rstrip("\n")
        elif result.status_code == 500:
            logging.error("Error in shortener service")
            logging.error(result.content)
            return None


class ParseContent(HTMLParser.HTMLParser):

    """Extend HTMLParser.HTMLParser.
    Parse an HTML string in input and puts the pure text, without the html
    formatting, in the attribute content.
    """

    def __init__(self, data):
        """
        Do the initialization of the parent class and starts the parse of the
        html in input
        """
        self.content = ''
        HTMLParser.HTMLParser.__init__(self)
        self.feed(data)
        self.close()

    def handle_data(self, data):
        """
        Puts the parsed content into the content variable.
        Override the parent handle_data function, it is called from the parent
        during the parsing when data is found
        """
        self.content = self.content.strip() + ' ' + data.strip()
